#include "SetObject.hpp"
#include "../../base/Defind.hpp"
#include "../Tool.hpp"
#include <unordered_map>

using namespace DBServer::Database;

// initialize for set
using Callback = std::function<void(SetObject&, CommandRequest&&, CommandRespond&)>;

std::unordered_map<int, Callback> SetObject::cb_table([]{
    std::unordered_map<int, Callback> temp;

    temp[COMMAND_GET] = [](SetObject& so, CommandRequest&& crq, CommandRespond& crp) {
        auto ret = so.get();
        crp.respond = "";
        int count = 0;
        for (auto ele : ret)
        {
            crp.respond += Translator::int_to_string(count);
            crp.respond += " ";
            crp.respond += ele;
            crp.respond += "\n";
        }
    };

    temp[COMMAND_SADD] = [](SetObject& so, CommandRequest&& crq, CommandRespond& crp) {
        auto ret = so.sadd(std::move(crq.command[COMMAND_VALUE]));
        if (ret) crp.respond = OK;
        else
        {
            crp.respond = SADD_SUCCESS;
        }
    };

    temp[COMMAND_SSIZE] = [](SetObject& so, CommandRequest&& crq, CommandRespond& crp) {
        auto ret = so.ssize();
        crp.respond = Translator::int_to_string(ret);
    };
    
    temp[COMMAND_SEXIST] = [](SetObject& so, CommandRequest&& crq, CommandRespond& crp) {
        auto ret = so.sexist(std::move(crq.command[COMMAND_VALUE]));
        if (ret)
        {
            crp.respond = SEXIT_TRUE;
        } else 
        {
            crp.respond = SEXIT_FALSE;
        }
    };

    temp[COMMAND_SPOP] = [](SetObject& so, CommandRequest&& crq, CommandRespond& crp) {
        auto ret = so.spop(std::move(crq.command[COMMAND_VALUE]));
        if (ret) 
        {
            crp.respond = SPOP_SUCCESS;
        } else 
        {
            crp.respond = SPOP_FAULT;
        }
    };

    return temp;
}());

void
SetObject::command_excute(CommandRespond& crp, CommandRequest&& crq, com_func_t& cft)
{
    cb_table[cft.second](*this, std::move(crq), crp);
}